# push/managers/push_manager.py
from typing import List, Dict
import threading
from database.connection import get_pending_tasks, mark_task_status
from push.adapters.unipush import UniPushAdapter
from core.exceptions import PushServiceError
from database.models import PushTask

class PushManager:
    """推送任务管理类"""

    def __init__(self):
        self.unipush = UniPushAdapter()

    def _process_single_task(self, task):
        """
        处理单个推送任务的辅助方法。
        :param task: 待处理的推送任务
        """
        results = {
            'success': 0,
            'failed': 0
        }
        try:
            # 解析模板数据
            template = task.template_data
            url = task.url

            # 调用UniPush推送
            push_result = self.unipush.push_by_template(
                cid=task.app_open_id,
                template_data={
                    'first': template.first,
                    'keyword1': template.keyword1,
                    'keyword2': template.keyword2,
                    'remark': template.remark
                },
                url=url
            )

            # 检查推送结果，根据日志中的响应格式修改判断逻辑
            if push_result.get('code') == 0 and push_result.get('msg') == 'success':
                mark_task_status(task.id, 2)  # 标记为执行成功
                results['success'] += 1
                print(f"推送成功: 任务ID={task.id}, 设备={task.app_open_id}")
            else:
                mark_task_status(task.id, 3)  # 标记为执行失败
                results['failed'] += 1
                print(f"推送失败: 任务ID={task.id}, 设备={task.app_open_id}, 原因={push_result.get('msg', '未知原因')}")

        except PushServiceError as e:
            mark_task_status(task.id, 3)  # 标记为执行失败
            results['failed'] += 1
            print(f"推送异常: 任务ID={task.id}, 错误={str(e)}")

        except Exception as e:
            mark_task_status(task.id, 3)  # 标记为执行失败
            results['failed'] += 1
            print(f"未知错误: 任务ID={task.id}, 错误={str(e)}")

        return results

    def process_pending_tasks(self, limit: int = 10) -> Dict[str, int]:
        """
        处理待推送任务，使用多线程提高效率。
        """
        results = {"success": 0, "failed": 0, "total": 0}
        tasks = get_pending_tasks(limit)
        results["total"] = len(tasks)

        threads = []
        for task in tasks:
            thread = threading.Thread(target=lambda t=task: self._update_results(results, t))
            threads.append(thread)
            thread.start()

        for thread in threads:
            thread.join()

        return results

    def _update_results(self, results, task):
        task_results = self._process_single_task(task)
        results['success'] += task_results['success']
        results['failed'] += task_results['failed']